#include "pageone.h"
#include "ui_pageone.h"
#include <QInputDialog>
#include <QLabel>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QMqttClient>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDateTime>
#include <QDebug>
#include <QPushButton>
Pageone::Pageone(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Pageone),
    tempThreshold(30), // 默认温度最高阈值
    tempMinThreshold(10), // 最低阈值默认10°C
    currentTemp(0.0), // 当前温度初始值（等待真实数据）
    isSwitch(false),  // 温度开关状态
    humidThreshold(60),   // 默认湿度阈值
    humidMinThreshold(30),    // 最小湿度阈值默认30%
    currentHumid(0.0),   // 当前湿度初始值（等待真实数据）
    isHumidSwitch(false), // 湿度开关状态
    currentFoodAmount(100),   // 初始食物数量（等待真实数据）
    isFoodDispensing(false),   // 初始未投喂
    deviceFd("")  // 🆕 初始化设备fd为空

{
    ui->setupUi(this);
    ui->tempCard_3->setText("--°C");  // 等待数据
    ui->humidCard_3->setText("--%");  // 等待数据
    ui->levelCard_3->setText("等待数据...");
    ui->label_5->setText("等待数据...");
    // 初始化食物显示
    ui->foodCard_3->setText("剩余--");


}


Pageone::~Pageone()
{
    delete ui;
}
void Pageone::checkTempSwitch()
{
    // 低于最低阈值
    if (currentTemp <= tempMinThreshold) {
        isSwitch = false; // 可根据实际需求调整开关状态
        ui->levelCard_3->setText("温度过低");
    }
    // 高于最高阈值
    else if (currentTemp >= tempThreshold) {
        isSwitch = true; // 可根据实际需求调整开关状态
        ui->levelCard_3->setText("温度过高");
    }
    // 在正常范围内
    else {
        isSwitch = false; // 可根据实际需求调整开关状态
        ui->levelCard_3->setText("温度正常");
    }
}

void Pageone::on_settingBtn_3_clicked()
{
    bool ok;

    // 1. 获取最高温度阈值
    int newMaxThreshold = QInputDialog::getInt(
        this,
        "设置温度最高阈值",
        "请输入最高温度阈值(°C)：",
        tempThreshold,  // 初始值
        10, 40, 1,      // 范围10-40°C
        &ok
        );
    if (!ok) return; // 用户取消则退出

    // 2. 获取最低温度阈值
    int newMinThreshold = QInputDialog::getInt(
        this,
        "设置温度最低阈值",
        "请输入最低温度阈值(°C)：",
        tempMinThreshold,  // 初始值
        10, 40, 1,         // 范围10-40°C
        &ok
        );
    if (!ok) return; // 用户取消则退出

    // 3. 校验：最低阈值必须小于最高阈值
    if (newMinThreshold >= newMaxThreshold) {
        QMessageBox::warning(this, "输入错误", "最低阈值不能大于等于最高阈值！");
        return;
    }

    // 4. 更新阈值并检查状态
    if (ok) {
        tempThreshold = newMaxThreshold;
        tempMinThreshold = newMinThreshold;
        checkTempSwitch();
        // 发送温度阈值信号
        emit tempThresholdChanged(tempThreshold, tempMinThreshold);

        // 🔄 发送所有设置到MQTT（包含温度、湿度、食物）
        sendAllSettings();
    }
}



void Pageone::checkHumidSwitch()
{
    // 低于最小阈值
    if (currentHumid <= humidMinThreshold) {
        isHumidSwitch = false; // 可根据实际需求调整状态
        ui->label_5->setText("湿度过低");
    }
    // 高于最大阈值
    else if (currentHumid >= humidThreshold) {
        isHumidSwitch = true; // 可根据实际需求调整状态
        ui->label_5->setText("湿度过高");
    }
    // 在正常范围内
    else {
        isHumidSwitch = false; // 可根据实际需求调整状态
        ui->label_5->setText("湿度正常");
    }
}

// 湿度阈值设置槽函数
void Pageone::on_alarmBtn_3_clicked()
{
    bool ok;

    // 1. 获取最大湿度阈值
    int newMaxHumid = QInputDialog::getInt(
        this,
        "设置湿度最大阈值",
        "请输入最大湿度阈值(%)：",
        humidThreshold,  // 初始值
        30, 80, 1,       // 范围30%-80%
        &ok
        );
    if (!ok) return; // 用户取消则退出

    // 2. 获取最小湿度阈值
    int newMinHumid = QInputDialog::getInt(
        this,
        "设置湿度最小阈值",
        "请输入最小湿度阈值(%)：",
        humidMinThreshold,  // 初始值
        30, 80, 1,          // 范围30%-80%
        &ok
        );
    if (!ok) return; // 用户取消则退出

    // 3. 校验：最小阈值必须小于最大阈值
    if (newMinHumid >= newMaxHumid) {
        QMessageBox::warning(this, "输入错误", "最小湿度阈值不能大于等于最大阈值！");
        return;
    }

    // 4. 更新阈值并检查状态
    if (ok) {
        humidThreshold = newMaxHumid;
        humidMinThreshold = newMinHumid;
        checkHumidSwitch();
        // 发送湿度阈值信号
        emit humidThresholdChanged(humidThreshold, humidMinThreshold);

        // 🔄 发送所有设置到MQTT（包含温度、湿度、食物）
        sendAllSettings();
    }
}



void Pageone::on_pushButton_2_clicked()
{
    // 弹出输入对话框，让用户输入新的食物数量
    bool ok;
    int newFoodAmount = QInputDialog::getInt(
        this,
        "更改食物数量",
        "请输入新的食物数量（单位）：",
        currentFoodAmount,  // 初始显示当前数量
        0, 1000, 1,         // 范围：0~1000，步长1（可根据需求调整）
        &ok
        );

    // 如果用户确认输入（点击"确定"）
    if (ok) {
        currentFoodAmount = newFoodAmount;  // 更新食物数量
        // 更新UI显示
        ui->foodCard_3->setText(QString("食物数量：%1").arg(currentFoodAmount));

        qDebug() << "食物数量已更新为:" << currentFoodAmount;

        // 🔄 发送所有设置到MQTT（包含温度、湿度、食物）
        sendAllSettings();
    }
}

void Pageone::on_pushButton_clicked()
{
    // 触发投喂动作（每次点击都触发一次投喂）
    qDebug() << "触发投喂动作，当前食物剩余:" << currentFoodAmount;

    // 更新UI显示
    ui->foodCard_3->setText(QString("剩余%1").arg(currentFoodAmount));

    // 发送MQTT投喂信号
    sendFeedingStatus();


}

// MQTT相关方法实现
void Pageone::setMqttClient(QMqttClient *client)
{
    m_mqttClient = client;

    if (m_mqttClient) {
        // 连接MQTT消息接收信号
        connect(m_mqttClient, &QMqttClient::messageReceived, this, &Pageone::onMqttMessageReceived);

        qDebug() << "Pageone MQTT客户端设置完成";
    }
}

void Pageone::setTopicPrefix(const QString &topicPrefix)
{
    m_topicPrefix = topicPrefix;
    qDebug() << "Pageone主题已更新为:" << m_topicPrefix;
}

void Pageone::subscribeTopics()
{
    if (!m_mqttClient) {
        qDebug() << "Pageone MQTT客户端未设置，无法订阅主题";
        return;
    }

    if (m_mqttClient->state() != QMqttClient::Connected) {
        qDebug() << "Pageone MQTT未连接，无法订阅主题";
        return;
    }

    // 订阅统一数据主题（收发数据都使用同一个主题）
    QString unifiedTopic = m_topicPrefix;
    auto unifiedSubscription = m_mqttClient->subscribe(unifiedTopic);
    if (unifiedSubscription) {
        qDebug() << "Pageone成功订阅统一数据主题:" << unifiedTopic;
    } else {
        qDebug() << "Pageone订阅统一数据主题失败:" << unifiedTopic;
    }

    qDebug() << "Pageone统一主题订阅完成";
}

void Pageone::sendFeedingStatus()
{
    if (!m_mqttClient) {
        qDebug() << "Pageone MQTT客户端未设置，无法发送投喂状态";
        return;
    }

    if (m_mqttClient->state() != QMqttClient::Connected) {
        qDebug() << "Pageone MQTT未连接，当前状态:" << m_mqttClient->state() << "，无法发送投喂状态";
        return;
    }

    try {
        // 创建投喂开启信号JSON（只在投喂开启时调用此函数）
        QJsonObject feedingData;

        // 添加设备fd（如果已接收到）
        feedingData["fd"] = deviceFd.toInt();  // QString转为int
        feedingData["feed"] = "1";  // 投喂开启命令


        QJsonDocument doc(feedingData);
        QString jsonString = doc.toJson(QJsonDocument::Compact);

        // 发送到统一数据主题（固定主题）
        QString unifiedTopic = "qtmqtt/topic1";
        qDebug() << "🍖 准备发送投喂命令 - 主题:" << unifiedTopic;
        qDebug() << "📦 消息内容:" << jsonString;
        
        int result = m_mqttClient->publish(unifiedTopic, jsonString.toUtf8());

        if (result == -1) {
            qDebug() << "❌ Pageone发送投喂命令失败，主题:" << unifiedTopic;
        } else {
            qDebug() << "✅ Pageone发送投喂命令成功，消息ID:" << result;
        }

    } catch (const std::exception &e) {
        qDebug() << "Pageone发送投喂状态时发生异常:" << e.what();
    } catch (...) {
        qDebug() << "Pageone发送投喂状态时发生未知异常";
    }
}

// 🆕 统一发送所有数据（温度+湿度+食物+阈值+状态）到一条MQTT消息中
void Pageone::sendAllSettings()
{
    if (!m_mqttClient) {
        qDebug() << "Pageone MQTT客户端未设置，无法发送数据";
        return;
    }

    if (m_mqttClient->state() != QMqttClient::Connected) {
        qDebug() << "Pageone MQTT未连接，当前状态:" << m_mqttClient->state() << "，无法发送数据";
        return;
    }

    try {
        // 创建统一数据JSON，包含温度、湿度、食物的实际值、阈值和状态
        QJsonObject allSettings;

        // 添加设备fd（如果已接收到）
        allSettings["fd"] = deviceFd.toInt();  // QString转为int
        
        // 温度相关设置（数字类型）
        allSettings["Tem_max"] = tempThreshold;
        allSettings["Tem_min"] = tempMinThreshold;

        // 湿度相关设置（数字类型）
        allSettings["Hum_max"] = humidThreshold;
        allSettings["Hum_min"] = humidMinThreshold;

        // 食物相关设置（数字类型）
        allSettings["food"] = currentFoodAmount;


        QJsonDocument doc(allSettings);
        QString jsonString = doc.toJson(QJsonDocument::Compact);

        // 发送到统一数据主题（固定主题）
        QString unifiedTopic = "qtmqtt/topic1";
        qDebug() << "🔔 准备发送统一设置MQTT消息 - 主题:" << unifiedTopic;
        qDebug() << "📦 消息内容:" << jsonString;

        int result = m_mqttClient->publish(unifiedTopic, jsonString.toUtf8());

        if (result == -1) {
            qDebug() << "❌ Pageone发送统一设置失败，主题:" << unifiedTopic;
        } else {
            qDebug() << "✅ Pageone发送统一设置成功，消息ID:" << result;
            qDebug() << "   ├─ 温度阈值:" << tempMinThreshold << "-" << tempThreshold << "°C";
            qDebug() << "   ├─ 湿度阈值:" << humidMinThreshold << "-" << humidThreshold << "%";
            qDebug() << "   └─ 食物量:" << currentFoodAmount;
        }

    } catch (const std::exception &e) {
        qDebug() << "Pageone发送统一设置时发生异常:" << e.what();
    } catch (...) {
        qDebug() << "Pageone发送统一设置时发生未知异常";
    }
}

void Pageone::onMqttMessageReceived(const QByteArray &message, const QMqttTopicName &topic)
{
    QString topicStr = topic.name();
    QString messageStr = QString::fromUtf8(message);

    qDebug() << "Pageone收到MQTT消息 - 主题:" << topicStr << "消息:" << messageStr;

    // 统一处理所有消息（包括McuToClient主题）
    handleUnifiedData(messageStr);
}

// 处理统一主题的数据
void Pageone::handleUnifiedData(const QString &message)
{
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error);

    if (error.error != QJsonParseError::NoError) {
        qDebug() << "Pageone统一数据JSON解析错误:" << error.errorString();
        return;
    }

    QJsonObject obj = doc.object();

    // 提取并保存fd值（如果存在）
    if (obj.contains("fd")) {
        // fd可能是int或string类型，统一转为QString
        if (obj["fd"].isDouble()) {
            deviceFd = QString::number(obj["fd"].toInt());  // int → QString
        } else {
            deviceFd = obj["fd"].toString();  // string → QString
        }
        qDebug() << "Pageone接收到设备fd:" << deviceFd;
    }

    // 根据消息内容判断消息类型（使用独立的if，一条消息可能包含多个字段）
    if (obj.contains("Tem")) {
        // 温度数据（值为字符串，需要先toString再转数字）
        QString tempStr = obj["Tem"].toString();
        double temperature = tempStr.toDouble();
        currentTemp = temperature;
        ui->tempCard_3->setText(QString("%1°C").arg(temperature, 0, 'f', 1));
        checkTempSwitch();
        emit temperatureChanged(temperature);
        qDebug() << "Pageone接收到温度数据:" << temperature << "°C";
    }
    
    if (obj.contains("Hum")) {
        // 湿度数据（值为字符串，需要先toString再转数字）
        QString humStr = obj["Hum"].toString();
        double humidity = humStr.toDouble();
        currentHumid = humidity;
        ui->humidCard_3->setText(QString("%1%").arg(humidity, 0, 'f', 1));
        checkHumidSwitch();
        emit humidityChanged(humidity);
        qDebug() << "Pageone接收到湿度数据:" << humidity << "%";
    }
    
    if (obj.contains("food")) {
        // 食物数据（值为字符串，需要先toString再转数字）
        QString foodStr = obj["food"].toString();
        int foodAmount = foodStr.toInt();
        currentFoodAmount = foodAmount;
        ui->foodCard_3->setText(QString("剩余%1").arg(currentFoodAmount));
        qDebug() << "Pageone接收到食物数据:" << foodAmount;
    }
    
    if (obj.contains("ALS")) {
        // 环境光数据（值为字符串，需要先toString再转数字）
        QString alsStr = obj["ALS"].toString();
        int als = alsStr.toInt();
        qDebug() << "Pageone接收到环境光数据:" << als;
        
        // 更新环境光显示
        ui->label_7->setText(QString::number(als));
    }
    
    
    if (obj.contains("Tem_max") || obj.contains("Tem_min")) {
        // 温度阈值设置
        if (obj.contains("Tem_max")) {
            tempThreshold = obj["Tem_max"].toInt();
        }
        if (obj.contains("Tem_min")) {
            tempMinThreshold = obj["Tem_min"].toInt();
        }
        emit tempThresholdChanged(tempThreshold, tempMinThreshold);
        qDebug() << "Pageone接收到温度阈值设置 - 最高:" << tempThreshold << "°C, 最低:" << tempMinThreshold << "°C";
    }
    
    if (obj.contains("Hum_max") || obj.contains("Hum_min")) {
        // 湿度阈值设置
        if (obj.contains("Hum_max")) {
            humidThreshold = obj["Hum_max"].toInt();
        }
        if (obj.contains("Hum_min")) {
            humidMinThreshold = obj["Hum_min"].toInt();
        }
        qDebug() << "Pageone接收到湿度阈值设置 - 最高:" << humidThreshold << "%, 最低:" << humidMinThreshold << "%";
    }
}

void Pageone::handleSensorData(const QString &message)
{
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error);

    if (error.error != QJsonParseError::NoError) {
        qDebug() << "Pageone JSON解析错误:" << error.errorString();
        return;
    }

    QJsonObject obj = doc.object();

    // 检查是否包含温度和湿度数据
    if (obj.contains("Tem") && obj.contains("Hum")) {
        double temperature = obj["Tem"].toDouble();
        double humidity = obj["Hum"].toDouble();

        // 更新UI显示
        ui->tempCard_3->setText(QString("%1°C").arg(temperature, 0, 'f', 1));
        ui->humidCard_3->setText(QString("%1%").arg(humidity, 0, 'f', 1));

        // 更新内部变量
        currentTemp = temperature;
        currentHumid = humidity;

        // 检查阈值状态
        checkTempSwitch();
        checkHumidSwitch();

        // 发射信号
        emit temperatureChanged(temperature);
        emit humidityChanged(humidity);

        qDebug() << "Pageone接收到传感器数据 - 温度:" << temperature << "湿度:" << humidity;
    }
}


// 分别处理不同主题的数据
void Pageone::handleTempData(const QString &message)
{
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error);

    if (error.error != QJsonParseError::NoError) {
        qDebug() << "Pageone温度数据JSON解析错误:" << error.errorString();
        return;
    }

    QJsonObject obj = doc.object();

    // 检查是否包含温度数据
    if (obj.contains("Tem")) {
        double temperature = obj["Tem"].toDouble();

        // 更新UI显示
        ui->tempCard_3->setText(QString("%1°C").arg(temperature, 0, 'f', 1));

        // 更新内部变量
        currentTemp = temperature;

        // 检查阈值状态
        checkTempSwitch();

        // 发射信号
        emit temperatureChanged(temperature);

        qDebug() << "Pageone接收到温度数据 - 温度:" << temperature;
    } else {
        qDebug() << "Pageone温度数据缺少temperature字段";
    }
}

void Pageone::handleHumidData(const QString &message)
{
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error);

    if (error.error != QJsonParseError::NoError) {
        qDebug() << "Pageone湿度数据JSON解析错误:" << error.errorString();
        return;
    }

    QJsonObject obj = doc.object();

    // 检查是否包含湿度数据
    if (obj.contains("Hum")) {
        double humidity = obj["Hum"].toDouble();

        // 更新UI显示
        ui->humidCard_3->setText(QString("%1%").arg(humidity, 0, 'f', 1));

        // 更新内部变量
        currentHumid = humidity;

        // 检查阈值状态
        checkHumidSwitch();

        // 发射信号
        emit humidityChanged(humidity);

        qDebug() << "Pageone接收到湿度数据 - 湿度:" << humidity;
    } else {
        qDebug() << "Pageone湿度数据缺少humidity字段";
    }
}

void Pageone::handleFoodData(const QString &message)
{
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error);

    if (error.error != QJsonParseError::NoError) {
        qDebug() << "Pageone食物数据JSON解析错误:" << error.errorString();
        return;
    }

    QJsonObject obj = doc.object();

    // 检查是否包含食物数据
    if (obj.contains("food")) {
        int foodAmount = obj["food"].toInt();

        // 更新内部变量
        currentFoodAmount = foodAmount;

        // 更新UI显示
        ui->foodCard_3->setText(QString("食物剩余：%1").arg(currentFoodAmount));

        qDebug() << "Pageone接收到食物数据 - 食物数量:" << foodAmount;
    } else {
        qDebug() << "Pageone食物数据缺少food_amount字段";
    }
}



void Pageone::on_cameraBtn_3_clicked()
{
    // 切换环境光开关状态
    static bool isLightOn = false;  // 静态变量保持状态
    
    isLightOn = !isLightOn;  // 切换状态
    
    // 创建JSON消息
    QJsonObject lightData;
    lightData["fd"] = deviceFd.toInt();  // QString转为int
    lightData["led"] = isLightOn ? "1" : "0";  // 开是1，关是0
    
    // 转换为JSON字符串
    QJsonDocument doc(lightData);
    QString message = doc.toJson(QJsonDocument::Compact);
    
    // 发送MQTT消息
    QString unifiedTopic = "qtmqtt/topic1";
    qDebug() << "准备发送环境光命令 - 主题:" << unifiedTopic;
    qDebug() << "消息内容:" << message;

    int result = m_mqttClient->publish(unifiedTopic, message.toUtf8());

    if (result == -1) {
        qDebug() << "❌ Pageone发送环境光命令失败，主题:" << unifiedTopic;
    } else {
        qDebug() << "✅ Pageone发送环境光命令成功，消息ID:" << result;
    }
}

